package com.atguigu.aclservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.aclservice.entity.Permission;
import com.atguigu.aclservice.entity.RolePermission;
import com.atguigu.aclservice.entity.User;
import com.atguigu.aclservice.helper.MemuHelper;
import com.atguigu.aclservice.helper.PermissionHelper;
import com.atguigu.aclservice.mapper.PermissionMapper;
import com.atguigu.aclservice.service.PermissionService;
import com.atguigu.aclservice.service.RolePermissionService;
import com.atguigu.aclservice.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 权限 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2020-01-12
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    private RolePermissionService rolePermissionService;
    
    @Autowired
    private UserService userService;
    
    //获取全部菜单
    @Override
    public List<Permission> queryAllMenu() {

        QueryWrapper<Permission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<Permission> permissionList = baseMapper.selectList(wrapper);

        List<Permission> result = bulid(permissionList);

        return result;
    }

    //根据角色获取菜单
    @Override
    public List<Permission> selectAllMenu(String roleId) {
        List<Permission> allPermissionList = baseMapper.selectList(new QueryWrapper<Permission>().orderByAsc("CAST(id AS SIGNED)"));

        //根据角色id获取角色权限
        List<RolePermission> rolePermissionList = rolePermissionService.list(new QueryWrapper<RolePermission>().eq("role_id",roleId));
        //转换给角色id与角色权限对应Map对象
//        List<String> permissionIdList = rolePermissionList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());
//        allPermissionList.forEach(permission -> {
//            if(permissionIdList.contains(permission.getId())) {
//                permission.setSelect(true);
//            } else {
//                permission.setSelect(false);
//            }
//        });
        for (int i = 0; i < allPermissionList.size(); i++) {
            Permission permission = allPermissionList.get(i);
            for (int m = 0; m < rolePermissionList.size(); m++) {
                RolePermission rolePermission = rolePermissionList.get(m);
                if(rolePermission.getPermissionId().equals(permission.getId())) {
                    permission.setSelect(true);
                }
            }
        }


        List<Permission> permissionList = bulid(allPermissionList);
        return permissionList;
    }

    //给角色分配权限
    @Override
    public void saveRolePermissionRealtionShip(String roleId, String[] permissionIds) {

        rolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", roleId));

  

        List<RolePermission> rolePermissionList = new ArrayList<>();
        for(String permissionId : permissionIds) {
            if(StringUtils.isEmpty(permissionId)) continue;
      
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionList.add(rolePermission);
        }
        rolePermissionService.saveBatch(rolePermissionList);
    }

    //递归删除菜单
    @Override
    public void removeChildById(String id) {
        List<String> idList = new ArrayList<>();
        this.selectChildListById(id, idList);

        idList.add(id);
        baseMapper.deleteBatchIds(idList);
    }

    //根据用户id获取用户菜单
    @Override
    public List<String> selectPermissionValueByUserId(String id) {

        List<String> selectPermissionValueList = null;
        if(this.isSysAdmin(id)) {
            //如果是系统管理员，获取所有权限
            selectPermissionValueList = baseMapper.selectAllPermissionValue();
        } else {
            selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
        }
        return selectPermissionValueList;
    }

    @Override
    public List<JSONObject> selectPermissionByUserId(String userId) {
        List<Permission> selectPermissionList = null;
        if(this.isSysAdmin(userId)) {
            //如果是超级管理员，获取所有菜单
            selectPermissionList = baseMapper.selectList(null);
        } else {
            selectPermissionList = baseMapper.selectPermissionByUserId(userId);
        }

        List<Permission> permissionList = PermissionHelper.bulid(selectPermissionList);
        List<JSONObject> result = MemuHelper.bulid(permissionList);
        return result;
    }

    /**
     * 判断用户是否系统管理员
     * @param userId
     * @return
     */
    private boolean isSysAdmin(String userId) {
        User user = userService.getById(userId);

        if(null != user && "admin".equals(user.getUsername())) {
            return true;
        }
        return false;
    }

    /**
     *	递归获取子节点
     * @param id
     * @param idList
     */
    private void selectChildListById(String id, List<String> idList) {
        List<Permission> childList = baseMapper.selectList(new QueryWrapper<Permission>().eq("pid", id).select("id"));
        childList.stream().forEach(item -> {
            idList.add(item.getId());
            this.selectChildListById(item.getId(), idList);
        });
    }

    /**
     * 使用递归方法建菜单
     * @param treeNodes
     * @return
     */
    private static List<Permission> bulid(List<Permission> treeNodes) {
        List<Permission> trees = new ArrayList<>();
        for (Permission treeNode : treeNodes) {
            if ("0".equals(treeNode.getPid())) {
                treeNode.setLevel(1);
                trees.add(findChildren(treeNode,treeNodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     * @param treeNodes
     * @return
     */
    private static Permission findChildren(Permission treeNode,List<Permission> treeNodes) {
        treeNode.setChildren(new ArrayList<Permission>());

        for (Permission it : treeNodes) {
            if(treeNode.getId().equals(it.getPid())) {
                int level = treeNode.getLevel() + 1;
                it.setLevel(level);
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }
                treeNode.getChildren().add(findChildren(it,treeNodes));
            }
        }
        return treeNode;
    }


    //========================递归查询所有菜单================================================

    /**
     * 获取全部菜单
     * @return
     */
    @Override
    public List<Permission> queryAllMenuGuli() {

        //1.查询菜单所有数据
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.orderByDesc("id");
        List<Permission> permissionList = baseMapper.selectList(permissionQueryWrapper);

        //2.把查询出来得菜单list集合进行封装
        List<Permission> resultList = bulidPermission(permissionList);

        return resultList;
    }
    /**
     * 把返回所有菜单list集合进行封装的方法（递归递归递归方式）
     * @param permissionList
     * @return
     */
    public static List<Permission> bulidPermission(List<Permission> permissionList) {

        //创建list集合，用于数据最终封装
        List<Permission> finalNode = new ArrayList<>();

        //把所有菜单得list集合遍历，得到顶层菜单 pid=0 设置leve1是1
        for (Permission permission : permissionList) {
            if (permission.getPid().equals("0")){
                //设置leve1是1
                permission.setLevel(1);
                //根据顶层菜单继续往下查询子菜单,并向finalNode中封装（真正递归查询）
                finalNode.add(selectChildren(permission,permissionList));
            }
        }
        return finalNode;
    }

    /**
     * 拿到顶级菜单，递归查询子菜单
     * @param permissionNode 一级菜单
     * @param permissionList
     * @return
     */
    private static Permission selectChildren(Permission permissionNode, List<Permission> permissionList) {
        //1.因为要向一层菜单里面放二层菜单，二层里面放三层菜单 ... 对象初始化传入空集合
        permissionNode.setChildren(new ArrayList<>());

        //根据一层的id和二层的pid一样就得到二层菜单,遍历所有菜单list集合,比较值
        for (Permission permission : permissionList) {
            //判断id和pid值是否相同
            if (permissionNode.getId().equals(permission.getPid())){
                //把父菜单level值+1
                int level = permissionNode.getLevel()+1;
                permission.setLevel(level);
                //如果Children为空,进行初始化操作
                if (permissionNode.getChildren() == null){
                    permissionNode.setChildren(new ArrayList<>());
                }
                //把查询出来的二级菜单放如一级菜单里面(递归)
                permissionNode.getChildren().add(selectChildren(permission,permissionList));
            }
        }
        return permissionNode;
    }

//==============================================================end====================================================


    //============递归删除菜单==================================
    @Override
    public void removeChildByIdGuli(String id) {
        //1.创建list集合封装删除菜单的id值
        List<String> ids = new ArrayList<>();
        //2.向ids设置要删除的id
        //递归查询相关id方法
        this.selectPermissionChildById(id,ids);
        //把当前id加入
        ids.add(id);
        //删除去ids
        baseMapper.deleteBatchIds(ids);
    }
    /**
     * 根据当前菜单id，查询菜单里面子菜单id，封装到list集合
     * @param id
     * @param idList
     */
    private void selectPermissionChildById(String id, List<String> idList) {
        /**
         * 查询指定列的id
         */
        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
        permissionQueryWrapper.eq("pid",id);
        permissionQueryWrapper.select("id");

        List<Permission> permissionList = baseMapper.selectList(permissionQueryWrapper);
        //把permissionList中的id值获取封装到ids中去，并递归操作
        for (Permission permission : permissionList) {
            idList.add(permission.getId());
            //递归查询
            this.selectPermissionChildById(permission.getId(),idList);
        }

        //使用表达式遍历permissionList,item是具体值
//        permissionList.stream().forEach(item ->{
//            idList.add(item.getId());
//            //递归查询
//            this.selectPermissionChildById(item.getId(),idList);
//        });

    }

    //=========================给角色分配菜单=======================
    @Override
    public void saveRolePermissionRealtionShipGuli(String roleId, String[] permissionIds) {
        //roleId角色id
        //permissionIds 多个菜单id

        //1.创建list集合用于封装添加数据
        List<RolePermission> rolePermissionList = new ArrayList<>();
        //2遍历菜单数组
        for (String permissionId : permissionIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionList.add(rolePermission);
        }
        //批量添加到角色菜单关系表中
        rolePermissionService.saveBatch(rolePermissionList);
    }
}
